{
 "metadata": {
  "name": "",
  "signature": "sha256:c4c31c2b338db98edaa6a6dbdf867efe0a8e86dca2ed829d97450b3c182cbc78"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "# Extracting Features from the Bike Sharing Dataset"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "%pylab inline"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Populating the interactive namespace from numpy and matplotlib\n"
       ]
      }
     ],
     "prompt_number": 1
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# first remove the headers by using the 'sed' command:\n",
      "# sed 1d hour.csv > hour_noheader.csv\n",
      "path = \"/PATH/hour_noheader.csv\"\n",
      "raw_data = sc.textFile(path)\n",
      "num_data = raw_data.count()\n",
      "records = raw_data.map(lambda x: x.split(\",\"))\n",
      "first = records.first()\n",
      "print first\n",
      "print num_data"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[u'1', u'2011-01-01', u'1', u'0', u'1', u'0', u'0', u'6', u'0', u'1', u'0.24', u'0.2879', u'0.81', u'0', u'3', u'13', u'16']\n",
        "17379\n"
       ]
      }
     ],
     "prompt_number": 2
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Extract the variables we want to keep\n",
      "\n",
      "_All variables:_\n",
      "\n",
      "`instant,dteday,season,yr,mnth,hr,holiday,weekday,workingday,weathersit,temp,atemp,hum,windspeed,casual,registered,cnt`\n",
      "\n",
      "_Variables to keep:_\n",
      "\n",
      "`season,yr,mnth,hr,holiday,weekday,workingday,weathersit,temp,atemp,hum,windspeed,cnt`"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Create feature mappings for categorical features"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# cache the dataset to speed up subsequent operations\n",
      "records.cache()\n",
      "# function to get the categorical feature mapping for a given variable column\n",
      "def get_mapping(rdd, idx):\n",
      "    return rdd.map(lambda fields: fields[idx]).distinct().zipWithIndex().collectAsMap()\n",
      "\n",
      "# we want to extract the feature mappings for columns 2 - 9\n",
      "# try it out on column 2 first\n",
      "print \"Mapping of first categorical feasture column: %s\" % get_mapping(records, 2)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Mapping of first categorical feasture column: {u'1': 0, u'3': 1, u'2': 2, u'4': 3}\n"
       ]
      }
     ],
     "prompt_number": 3
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# extract all the catgorical mappings\n",
      "mappings = [get_mapping(records, i) for i in range(2,10)]\n",
      "cat_len = sum(map(len, mappings))\n",
      "num_len = len(records.first()[11:15])\n",
      "total_len = num_len + cat_len\n",
      "print \"Feature vector length for categorical features: %d\" % cat_len \n",
      "print \"Feature vector length for numerical features: %d\" % num_len\n",
      "print \"Total feature vector length: %d\" % total_len"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Feature vector length for categorical features: 57\n",
        "Feature vector length for numerical features: 4\n",
        "Total feature vector length: 61\n"
       ]
      }
     ],
     "prompt_number": 4
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Create Feature Vectors"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# required imports\n",
      "from pyspark.mllib.regression import LabeledPoint\n",
      "import numpy as np\n",
      "\n",
      "# function to use the feature mappings to extract binary feature vectors, and concatenate with\n",
      "# the numerical feature vectors\n",
      "def extract_features(record):\n",
      "    cat_vec = np.zeros(cat_len)\n",
      "    i = 0\n",
      "    step = 0\n",
      "    for field in record[2:9]:\n",
      "        m = mappings[i]\n",
      "        idx = m[field]\n",
      "        cat_vec[idx + step] = 1\n",
      "        i = i + 1\n",
      "        step = step + len(m)\n",
      "    \n",
      "    num_vec = np.array([float(field) for field in record[10:14]])\n",
      "    return np.concatenate((cat_vec, num_vec))\n",
      "\n",
      "# function to extract the label from the last column\n",
      "def extract_label(record):\n",
      "    return float(record[-1])\n",
      "\n",
      "data = records.map(lambda r: LabeledPoint(extract_label(r), extract_features(r)))\n",
      "first_point = data.first()\n",
      "print \"Raw data: \" + str(first[2:])\n",
      "print \"Label: \" + str(first_point.label)\n",
      "print \"Linear Model feature vector:\\n\" + str(first_point.features)\n",
      "print \"Linear Model feature vector length: \" + str(len(first_point.features))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Raw data: [u'1', u'0', u'1', u'0', u'0', u'6', u'0', u'1', u'0.24', u'0.2879', u'0.81', u'0', u'3', u'13', u'16']\n",
        "Label: 16.0\n",
        "Linear Model feature vector:\n",
        "[1.0,0.0,0.0,0.0,0.0,1.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,1.0,0.0,0.0,0.0,0.0,0.24,0.2879,0.81,0.0]\n",
        "Linear Model feature vector length: 61\n"
       ]
      }
     ],
     "prompt_number": 5
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# we need a separate set of feature vectors for the decision tree\n",
      "def extract_features_dt(record):\n",
      "    return np.array(map(float, record[2:14]))\n",
      "    \n",
      "data_dt = records.map(lambda r: LabeledPoint(extract_label(r), extract_features_dt(r)))\n",
      "first_point_dt = data_dt.first()\n",
      "print \"Decision Tree feature vector: \" + str(first_point_dt.features)\n",
      "print \"Decision Tree feature vector length: \" + str(len(first_point_dt.features))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Decision Tree feature vector: [1.0,0.0,1.0,0.0,0.0,6.0,0.0,1.0,0.24,0.2879,0.81,0.0]\n",
        "Decision Tree feature vector length: 12\n"
       ]
      }
     ],
     "prompt_number": 6
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "# Training a Regression Model"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from pyspark.mllib.regression import LinearRegressionWithSGD\n",
      "from pyspark.mllib.tree import DecisionTree\n",
      "help(LinearRegressionWithSGD.train)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Help on method train in module pyspark.mllib.regression:\n",
        "\n",
        "train(cls, data, iterations=100, step=1.0, miniBatchFraction=1.0, initialWeights=None, regParam=0.0, regType=None, intercept=False) method of __builtin__.type instance\n",
        "    Train a linear regression model on the given data.\n",
        "    \n",
        "    :param data:              The training data.\n",
        "    :param iterations:        The number of iterations (default: 100).\n",
        "    :param step:              The step parameter used in SGD\n",
        "                              (default: 1.0).\n",
        "    :param miniBatchFraction: Fraction of data to be used for each SGD\n",
        "                              iteration.\n",
        "    :param initialWeights:    The initial weights (default: None).\n",
        "    :param regParam:          The regularizer parameter (default: 0.0).\n",
        "    :param regType:           The type of regularizer used for training\n",
        "                              our model.\n",
        "    \n",
        "                              :Allowed values:\n",
        "                                 - \"l1\" for using L1 regularization (lasso),\n",
        "                                 - \"l2\" for using L2 regularization (ridge),\n",
        "                                 - None for no regularization\n",
        "    \n",
        "                                 (default: None)\n",
        "    \n",
        "    @param intercept:         Boolean parameter which indicates the use\n",
        "                              or not of the augmented representation for\n",
        "                              training data (i.e. whether bias features\n",
        "                              are activated or not).\n",
        "\n"
       ]
      }
     ],
     "prompt_number": 7
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "help(DecisionTree.trainRegressor)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Help on method trainRegressor in module pyspark.mllib.tree:\n",
        "\n",
        "trainRegressor(cls, data, categoricalFeaturesInfo, impurity='variance', maxDepth=5, maxBins=32, minInstancesPerNode=1, minInfoGain=0.0) method of __builtin__.type instance\n",
        "    Train a DecisionTreeModel for regression.\n",
        "    \n",
        "    :param data: Training data: RDD of LabeledPoint.\n",
        "                 Labels are real numbers.\n",
        "    :param categoricalFeaturesInfo: Map from categorical feature index\n",
        "                                    to number of categories.\n",
        "                                    Any feature not in this map\n",
        "                                    is treated as continuous.\n",
        "    :param impurity: Supported values: \"variance\"\n",
        "    :param maxDepth: Max depth of tree.\n",
        "                     E.g., depth 0 means 1 leaf node.\n",
        "                     Depth 1 means 1 internal node + 2 leaf nodes.\n",
        "    :param maxBins: Number of bins used for finding splits at each node.\n",
        "    :param minInstancesPerNode: Min number of instances required at child\n",
        "                                nodes to create the parent split\n",
        "    :param minInfoGain: Min info gain required to create a split\n",
        "    :return: DecisionTreeModel\n",
        "    \n",
        "    Example usage:\n",
        "    \n",
        "    >>> from pyspark.mllib.regression import LabeledPoint\n",
        "    >>> from pyspark.mllib.tree import DecisionTree\n",
        "    >>> from pyspark.mllib.linalg import SparseVector\n",
        "    >>>\n",
        "    >>> sparse_data = [\n",
        "    ...     LabeledPoint(0.0, SparseVector(2, {0: 0.0})),\n",
        "    ...     LabeledPoint(1.0, SparseVector(2, {1: 1.0})),\n",
        "    ...     LabeledPoint(0.0, SparseVector(2, {0: 0.0})),\n",
        "    ...     LabeledPoint(1.0, SparseVector(2, {1: 2.0}))\n",
        "    ... ]\n",
        "    >>>\n",
        "    >>> model = DecisionTree.trainRegressor(sc.parallelize(sparse_data), {})\n",
        "    >>> model.predict(SparseVector(2, {1: 1.0}))\n",
        "    1.0\n",
        "    >>> model.predict(SparseVector(2, {1: 0.0}))\n",
        "    0.0\n",
        "    >>> rdd = sc.parallelize([[0.0, 1.0], [0.0, 0.0]])\n",
        "    >>> model.predict(rdd).collect()\n",
        "    [1.0, 0.0]\n",
        "\n"
       ]
      }
     ],
     "prompt_number": 8
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Train a Regression Model on the Bike Sharing Dataset"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "linear_model = LinearRegressionWithSGD.train(data, iterations=10, step=0.1, intercept=False)\n",
      "true_vs_predicted = data.map(lambda p: (p.label, linear_model.predict(p.features)))\n",
      "print \"Linear Model predictions: \" + str(true_vs_predicted.take(5))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Linear Model predictions: [(16.0, 119.30920003093597), (40.0, 116.95463511937379), (32.0, 116.57294610647752), (13.0, 116.43535423855656), (1.0, 116.221247828503)]\n"
       ]
      }
     ],
     "prompt_number": 9
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# we pass in an mepty mapping for categorical feature size {}\n",
      "dt_model = DecisionTree.trainRegressor(data_dt, {})\n",
      "preds = dt_model.predict(data_dt.map(lambda p: p.features))\n",
      "actual = data.map(lambda p: p.label)\n",
      "true_vs_predicted_dt = actual.zip(preds)\n",
      "print \"Decision Tree predictions: \" + str(true_vs_predicted_dt.take(5))\n",
      "print \"Decision Tree depth: \" + str(dt_model.depth())\n",
      "print \"Decision Tree number of nodes: \" + str(dt_model.numNodes())"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Decision Tree predictions: [(16.0, 54.913223140495866), (40.0, 54.913223140495866), (32.0, 53.171052631578945), (13.0, 14.284023668639053), (1.0, 14.284023668639053)]\n",
        "Decision Tree depth: 5\n",
        "Decision Tree number of nodes: 63\n"
       ]
      }
     ],
     "prompt_number": 10
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Perfomance Metrics"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# set up performance metrics functions \n",
      "\n",
      "def squared_error(actual, pred):\n",
      "    return (pred - actual)**2\n",
      "\n",
      "def abs_error(actual, pred):\n",
      "    return np.abs(pred - actual)\n",
      "\n",
      "def squared_log_error(pred, actual):\n",
      "    return (np.log(pred + 1) - np.log(actual + 1))**2"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 11
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### Linear Model"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# compute performance metrics for linear model\n",
      "mse = true_vs_predicted.map(lambda (t, p): squared_error(t, p)).mean()\n",
      "mae = true_vs_predicted.map(lambda (t, p): abs_error(t, p)).mean()\n",
      "rmsle = np.sqrt(true_vs_predicted.map(lambda (t, p): squared_log_error(t, p)).mean())\n",
      "print \"Linear Model - Mean Squared Error: %2.4f\" % mse\n",
      "print \"Linear Model - Mean Absolute Error: %2.4f\" % mae\n",
      "print \"Linear Model - Root Mean Squared Log Error: %2.4f\" % rmsle"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Linear Model - Mean Squared Error: 28166.3824\n",
        "Linear Model - Mean Absolute Error: 129.4506\n",
        "Linear Model - Root Mean Squared Log Error: 1.4974\n"
       ]
      }
     ],
     "prompt_number": 12
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### Decision Tree Model"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# compute performance metrics for decision tree model\n",
      "mse_dt = true_vs_predicted_dt.map(lambda (t, p): squared_error(t, p)).mean()\n",
      "mae_dt = true_vs_predicted_dt.map(lambda (t, p): abs_error(t, p)).mean()\n",
      "rmsle_dt = np.sqrt(true_vs_predicted_dt.map(lambda (t, p): squared_log_error(t, p)).mean())\n",
      "print \"Decision Tree - Mean Squared Error: %2.4f\" % mse_dt\n",
      "print \"Decision Tree - Mean Absolute Error: %2.4f\" % mae_dt\n",
      "print \"Decision Tree - Root Mean Squared Log Error: %2.4f\" % rmsle_dt"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Decision Tree - Mean Squared Error: 11560.7978\n",
        "Decision Tree - Mean Absolute Error: 71.0969\n",
        "Decision Tree - Root Mean Squared Log Error: 0.6259\n"
       ]
      }
     ],
     "prompt_number": 13
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#### Using the categorical feature mapping for Decision Tree"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# we create the categorical feature mapping for decision trees\n",
      "cat_features = dict([(i - 2, len(get_mapping(records, i)) + 1) for i in range(2,10)])\n",
      "print \"Categorical feature size mapping %s\" % cat_features\n",
      "# train the model again\n",
      "dt_model_2 = DecisionTree.trainRegressor(data_dt, categoricalFeaturesInfo=cat_features)\n",
      "preds_2 = dt_model_2.predict(data_dt.map(lambda p: p.features))\n",
      "actual_2 = data.map(lambda p: p.label)\n",
      "true_vs_predicted_dt_2 = actual_2.zip(preds_2)\n",
      "# compute performance metrics for decision tree model\n",
      "mse_dt_2 = true_vs_predicted_dt_2.map(lambda (t, p): squared_error(t, p)).mean()\n",
      "mae_dt_2 = true_vs_predicted_dt_2.map(lambda (t, p): abs_error(t, p)).mean()\n",
      "rmsle_dt_2 = np.sqrt(true_vs_predicted_dt_2.map(lambda (t, p): squared_log_error(t, p)).mean())\n",
      "print \"Decision Tree - Mean Squared Error: %2.4f\" % mse_dt_2\n",
      "print \"Decision Tree - Mean Absolute Error: %2.4f\" % mae_dt_2\n",
      "print \"Decision Tree - Root Mean Squared Log Error: %2.4f\" % rmsle_dt_2"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Categorical feature size mapping {0: 5, 1: 3, 2: 13, 3: 25, 4: 3, 5: 8, 6: 3, 7: 5}\n",
        "Decision Tree - Mean Squared Error: 7912.5642"
       ]
      },
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "\n",
        "Decision Tree - Mean Absolute Error: 59.4409\n",
        "Decision Tree - Root Mean Squared Log Error: 0.6192\n"
       ]
      }
     ],
     "prompt_number": 14
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "# Transforming the Target Variable\n",
      "## Distributon of Raw Target"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "targets = records.map(lambda r: float(r[-1])).collect()\n",
      "hist(targets, bins=40, color='lightblue', normed=True)\n",
      "fig = matplotlib.pyplot.gcf()\n",
      "fig.set_size_inches(16, 10)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "iVBORw0KGgoAAAANSUhEUgAAA7YAAAJPCAYAAABIEEj9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X+wpedB0PHv5W6KaZnp3tXUsMlioImmTUcIPzYhI7JA\n0TQ6yTBRSh2hpH80Uw34ayCtzmgyHQdBBYyRmLGJRkeIDkEaxtSCDldwkLTVNhbMQjY2NruRFLvJ\njBN/kCzrH+/Z5uZ2d8+5m3Oz99n9fGbO7HnPeZ/nvhfeTvu973ueUwAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAADAElxfHayeqG4/xT53zd5/rLp6gbH7q49Vn6w+Xn3Dcg8ZAAAAJqvVoeqy6oLqU9Vb\nNu1zQ/XI7Pk11a8uMHa9+uOz5++ofnHZBw4AAMD54UvmvL+/KU6fql6sHqxu2rTPjdUDs+ePVrur\ni+eM/R/VG2fPd1dHzvD4AQAAOM/tmvP+JdXTG7YPN12VnbfPJdXe04x9f/Ufqr/TFNffuKWjBgAA\ngJl5V2yPLzjPyhZ/7n3V91dfUf2l6v4tjgcAAIBq/hXbI9W+Ddv7mq68nm6fS2f7XHCasfurt8+e\n/3T1oZP98De/+c3Hn3zyyTmHCAAAwKCerC5/tZPMC9tPVFc0LQD1TPXO6l2b9nm4uq3pM7TXVs9X\nz1afP83YQ9U3V/+++tbqN0/2w5988sk+/elPb+HXWcyePXvau3fv0ueFk7njjju64447zvZhwKvm\nXOZc4DzmXOFc5lyxsrLy5mXMMy9sX2qK1o82rXJ8X/V4devs/XubVkS+oSlWX6humTO26r3VP6i+\ntPo/s+2T+hM3fUe7Lph3mIt78XdebHXleJ9xJRgAAOCcsEgxfmT22OjeTdu3bWFsTVeCNy9CdVJ/\n/YGfbu2iNy2y60I+d+RwH3z3zUubDwAAgLNr3uJRwKt04MCBs30IsBTOZc4FzmPOFc5leKWtrmb8\nWjv+oV/+1LZcsT3y9GeXNicAAABbt7KyUkvoUldsAQAAGJqwBQAAYGjCFgAAgKEJWwAAAIYmbAEA\nABiasAUAAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIWAACAoQlbAAAAhiZsAQAAGJqwBQAA\nYGjCFgAAgKEJWwAAAIYmbAEAABiasAUAAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIWAACA\noQlbAAAAhiZsAQAAGJqwBQAAYGjCFgAAgKEJWwAAAIYmbAEAABiasAUAAGBowhYAAIChCVsAAACG\nJmwBAAAYmrAFAABgaMIWAACAoQlbAAAAhiZsAQAAGJqwBQAAYGjCFgAAgKEJWwAAAIYmbAEAABia\nsAUAAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIWAACAoQlbAAAAhiZsAQAAGJqwBQAAYGjC\nFgAAgKEJWwAAAIYmbAEAABiasAUAAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIWAACAoS0S\nttdXB6snqttPsc9ds/cfq65eYOyD1Sdnj8/M/gUAAIAt2zXn/dXq7urt1ZHq49XD1eMb9rmhury6\norqmuqe6ds7Y79ow/u9Uz7/K3wMAAIDz1LwrtvurQ9VT1YtNV1pv2rTPjdUDs+ePVrurixccu1J9\nZ/VTZ3LwAAAAMC9sL6me3rB9ePbaIvvsXWDsN1XPVk8ueLwAAADwCvPC9viC86yc4c9/V/WTZzgW\nAAAA5n7G9ki1b8P2vqYrr6fb59LZPhfMGbur+o7qa093AB++/54ufP0bqrpq/3W97Zrr5hwyAAAA\nO9H6+nrr6+tLn3feldZd1W9U31Y9U32s6Srr5sWjbpv9e23147N/5429vmml5G85zc8//qFf/lRr\nF71p8d9ojs8dOdwH331zR57+7NLmBAAAYOtWVlbqzO8A/oJ5V2xfaorWjzatcnxfU5jeOnv/3uqR\npqg9VL1Q3TJn7AnvzKJRAAAAvErzwrbqI7PHRvdu2r5tC2NPuOUUrwMAAMDC5i0eBQAAADuasAUA\nAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIWAACAoQlbAAAAhiZsAQAAGJqwBQAAYGjCFgAA\ngKEJWwAAAIYmbAEAABiasAUAAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIWAACAoQlbAAAA\nhiZsAQAAGJqwBQAAYGjCFgAAgKEJWwAAAIYmbAEAABiasAUAAGBowhYAAIChCVsAAACGJmwBAAAY\nmrAFAABgaMIWAACAoQlbAAAAhiZsAQAAGJqwBQAAYGjCFgAAgKEJWwAAAIYmbAEAABiasAUAAGBo\nwhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIWAACAoQlbAAAAhiZsAQAAGJqwBQAAYGjCFgAAgKEJ\nWwAAAIYmbAEAABiasAUAAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIWAACAoQlbAAAAhiZs\nAQAAGJqwBQAAYGjCFgAAgKEJWwAAAIYmbAEAABjaImF7fXWweqK6/RT73DV7/7Hq6gXHfl/1ePVr\n1Q8vfsgAAADwsl1z3l+t7q7eXh2pPl493BSkJ9xQXV5dUV1T3VNdO2fst1Q3Vn+4erG6aCm/DQAA\nAOedeVds91eHqqeaAvTB6qZN+9xYPTB7/mi1u7p4ztj3VT80e73qt8/w+AEAADjPzQvbS6qnN2wf\nnr22yD57TzP2iuqPVr9arVdfv5WDBgAAgBPm3Yp8fMF5Vs7g56413bL8DdW/rL7qZDt++P57uvD1\nb6jqqv3X9bZrrtvijwIAAGAnWF9fb319fenzzgvbI9W+Ddv7mq68nm6fS2f7XHCasYern5k9/3j1\nu9XvrT6/+QBues/7WrvoTXMOEwAAgJ3uwIEDHThw4Avbd95551LmnXcr8ieabhu+rHpd9c6mBaA2\nerj6ntnza6vnq2fnjP3Z6ltnz//g7P0viloAAACYZ94V25eq26qPNq1yfF/Tqsa3zt6/t3qkaWXk\nQ9UL1S1zxlbdP3t8uvqdXg5jAAAA2JJ5YVv1kdljo3s3bd+2hbE1rYb83Qv8bAAAADitebciAwAA\nwI4mbAEAABiasAUAAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIWAACAoQlbAAAAhiZsAQAA\nGJqwBQAAYGjCFgAAgKEJWwAAAIYmbAEAABiasAUAAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABg\naMIWAACAoQlbAAAAhiZsAQAAGJqwBQAAYGjCFgAAgKEJWwAAAIYmbAEAABiasAUAAGBowhYAAICh\nCVsAAACGJmwBAAAYmrAFAABgaMIWAACAoQlbAAAAhiZsAQAAGJqwBQAAYGjCFgAAgKEJWwAAAIYm\nbAEAABiasAUAAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIWAACAoQlbAAAAhiZsAQAAGJqw\nBQAAYGjCFgAAgKEJWwAAAIYmbAEAABiasAUAAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIW\nAACAoQlbAAAAhiZsAQAAGJqwBQAAYGjCFgAAgKEtErbXVwerJ6rbT7HPXbP3H6uuXmDsHdXh6pOz\nx/VbOWgAAAA4Ydec91eru6u3V0eqj1cPV49v2OeG6vLqiuqa6p7q2jljj1c/OnsAAADAGZt3xXZ/\ndah6qnqxerC6adM+N1YPzJ4/Wu2uLl5g7MqZHzYAAABM5oXtJdXTG7YPz15bZJ+9c8Z+X9Oty/c1\nxTAAAABs2bywPb7gPFu9+npP9ZXV11T/o/q7WxwPAAAA1fzP2B6p9m3Y3td05fV0+1w62+eC04z9\n3IbXP1T93KkO4MP339OFr39DVVftv663XXPdnEMGAABgJ1pfX299fX3p88670rqr+o3q26pnqo9V\n7+qLF4+6bfbvtdWPz/493dgvb7pSW/WXqm+o/sxJfv7xD/3yp1q76E1b/b1O6XNHDvfBd9/ckac/\nu7Q5AQAA2LqVlZVawvpL867YvtQUrR9tWuX4vqYwvXX2/r3VI01Re6h6obplztiqH266Dfl49ZkN\n8wEAAMCWzAvbqo/MHhvdu2n7ti2MrfqeBX4uAAAAzDVv8SgAAADY0YQtAAAAQxO2AAAADE3YAgAA\nMDRhCwAAwNCELQAAAEMTtgAAAAxN2AIAADA0YQsAAMDQhC0AAABDE7YAAAAMTdgCAAAwNGELAADA\n0IQtAAAAQxO2AAAADE3YAgAAMDRhCwAAwNCELQAAAEMTtgAAAAxN2AIAADA0YQsAAMDQhC0AAABD\nE7YAAAAMTdgCAAAwNGELAADA0IQtAAAAQxO2AAAADE3YAgAAMDRhCwAAwNCELQAAAEMTtgAAAAxN\n2AIAADA0YQsAAMDQhC0AAABDE7YAAAAMTdgCAAAwNGELAADA0IQtAAAAQxO2AAAADE3YAgAAMDRh\nCwAAwNCELQAAAEMTtgAAAAxN2AIAADA0YQsAAMDQhC0AAABDE7YAAAAMTdgCAAAwNGELAADA0IQt\nAAAAQxO2AAAADE3YAgAAMDRhCwAAwNCELQAAAEMTtgAAAAxN2AIAADA0YQsAAMDQhC0AAABDE7YA\nAAAMTdgCAAAwNGELAADA0BYJ2+urg9UT1e2n2Oeu2fuPVVdvYexfqX632rPg8QIAAMArzAvb1eru\npkB9a/Wu6i2b9rmhury6onpvdc+CY/dV31799zM/fAAAAM5388J2f3Woeqp6sXqwumnTPjdWD8ye\nP1rtri5eYOyPVj94xkcOAAAAzQ/bS6qnN2wfnr22yD57TzP2ptn2f9ni8QIAAMAr7Jrz/vEF51nZ\nws+8sPqrTbchn8l4AAAA+IJ5YXuk6bOwJ+xrutJ6un0une1zwSnGvrm6rGmhqRP7/6emW5c/t/kA\nPnz/PV34+jdUddX+63rbNdfNOWQAAAB2ovX19dbX15c+77wrpbuq36i+rXqm+ljTIlCPb9jnhuq2\n2b/XVj8++3eRsVWfqb6uOnqSn3/8Q7/8qdYuetPiv9EcnztyuA++++aOPP3Zpc0JAADA1q2srNQS\n7uCdd8X2paZo/WjTKsf3NYXprbP3760eaYraQ9UL1S1zxm626O3OAAAA8EXmhW3VR2aPje7dtH3b\nFsZu9lULHAMAAACc1LxVkQEAAGBHE7YAAAAMTdgCAAAwNGELAADA0IQtAAAAQxO2AAAADE3YAgAA\nMDRhCwAAwNCELQAAAEMTtgAAAAxN2AIAADA0YQsAAMDQhC0AAABDE7YAAAAMTdgCAAAwNGELAADA\n0IQtAAAAQxO2AAAADE3YAgAAMDRhCwAAwNCELQAAAEMTtgAAAAxN2AIAADA0YQsAAMDQhC0AAABD\nE7YAAAAMTdgCAAAwNGELAADA0IQtAAAAQxO2AAAADE3YAgAAMDRhCwAAwNCELQAAAEMTtgAAAAxN\n2AIAADA0YQsAAMDQhC0AAABD23W2D+Bs+Nyzv9XKysrS5929ttZzR48ufV4AAABO7bwM25defLGH\nDj6z9HlvvnLv0ucEAADg9NyKDAAAwNCELQAAAEMTtgAAAAxN2AIAADA0YQsAAMDQhC0AAABDE7YA\nAAAMTdgCAAAwNGELAADA0IQtAAAAQxO2AAAADE3YAgAAMDRhCwAAwNCELQAAAEMTtgAAAAxN2AIA\nADA0YQsAAMDQhC0AAABDE7YAAAAMTdgCAAAwNGELAADA0IQtAAAAQ1skbK+vDlZPVLefYp+7Zu8/\nVl29wNgPzvb9VPXvqn1bOmoAAACYmRe2q9XdTYH61upd1Vs27XNDdXl1RfXe6p4Fxv5I9dXV11Q/\nW/2NV/NLAAAAcP6aF7b7q0PVU9WL1YPVTZv2ubF6YPb80Wp3dfGcsf9rw/gvq/7nmRw8AAAA7Jrz\n/iXV0xu2D1fXLLDPJdXeOWP/ZvXd1f+url38kAEAAOBl867YHl9wnpUz+Nl/rfqK6p9UP3YG4wEA\nAGDuFdsjvXJhp31NV15Pt8+ls30uWGBs1U9Wj5zqAD58/z1d+Po3VHXV/ut62zXXzTlkAAAAdqL1\n9fXW19eXPu+8sP1E06JQl1XPVO9sWgRqo4er25o+Q3tt9Xz1bPX504y9omml5Jo+d/vJUx3ATe95\nX2sXvWmR3wUAAIAd7MCBAx04cOAL23feeedS5p0Xti81RetHm1Y5vq96vLp19v69TVdbb2haKOqF\n6pY5Y6t+qPpD1bHqyep9r/5XAQAA4Hw0L2yrPjJ7bHTvpu3btjC26k8t8HMBAABgrnmLRwEAAMCO\nJmwBAAAYmrAFAABgaMIWAACAoQlbAAAAhiZsAQAAGJqwBQAAYGjCFgAAgKEJWwAAAIYmbAEAABia\nsAUAAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIWAACAoQlbAAAAhrbrbB/AuWR1dbWVlZWl\nz7t7ba3njh5d+rwAAADnAmG7RMeOHeuhg88sfd6br9y79DkBAADOFW5FBgAAYGjCFgAAgKEJWwAA\nAIYmbAEAABiasAUAAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIWAACAoQlbAAAAhiZsAQAA\nGJqwBQAAYGjCFgAAgKEJWwAAAIYmbAEAABiasAUAAGBowhYAAIChCVsAAACGJmwBAAAY2q6zfQDM\nt7q62srKytLn3b221nNHjy59XgAAgNeSsB3AsWPHeujgM0uf9+Yr9y59TgAAgNeaW5EBAAAYmrAF\nAABgaMIWAACAoQlbAAAAhiZsAQAAGJpVkc9jvkYIAAA4Fwjb85ivEQIAAM4Fwpal244rwa4CAwAA\npyJsWbrtuBLsKjAAAHAqFo8CAABgaMIWAACAoQlbAAAAhiZsAQAAGJqwBQAAYGjCFgAAgKEJWwAA\nAIbme2wZwurqaisrK0ufd/faWs8dPbr0eQEAgNeOsGUIx44d66GDzyx93puv3Lv0OQEAgNeWsOW8\n5kowAACMT9hyXnMlGAAAxrfo4lHXVwerJ6rbT7HPXbP3H6uuXmDs364en+3/M9UbFz5qAAAAmFkk\nbFeru5sC9a3Vu6q3bNrnhury6orqvdU9C4z9+eqq6qur36w+cKa/BAAAAOevRcJ2f3Woeqp6sXqw\numnTPjdWD8yeP1rtri6eM/YXqt/dMObSMzh+AAAAznOLhO0l1dMbtg/PXltkn70LjK16T/XIAscC\nAAAAr7DI4lHHF5zrTJeW/WvV71Q/ebI3P3z/PV34+jdUddX+63rbNded4Y8BAADgbFpfX299fX3p\n8y4StkeqfRu29zVdeT3dPpfO9rlgztjvbfp87red6off9J73tXbRmxY4TAAAAHayAwcOdODAgS9s\n33nnnUuZd5FbkT/RtCjUZdXrqndWD2/a5+Hqe2bPr62er56dM/b66geaPnP7f8/w+AEAADjPLXLF\n9qXqtuqjTasc39f0NT23zt6/t+nzsTc0LRT1QnXLnLFVf78pdn9htv0fqz935r8KAAAA56NFwrbq\nI7PHRvdu2r5tC2NrupILAAAAr8oityIDAADAjiVsAQAAGJqwBQAAYGjCFgAAgKEJWwAAAIYmbAEA\nABiasAUAAGBowhYAAIChCVsAAACGtutsHwCci1ZXV1tZWVn6vLvX1nru6NGlzwsAACMTtrANjh07\n1kMHn1n6vDdfuXfpcwIAwOjcigwAAMDQhC0AAABDE7YAAAAMTdgCAAAwNItHwUC2Y7VlKy0DADA6\nYQsD2Y7Vlq20DADA6NyKDAAAwNCELQAAAEMTtgAAAAxN2AIAADA0YQsAAMDQhC0AAABDE7YAAAAM\nTdgCAAAwNGELAADA0IQtAAAAQxO2AAAADE3YAgAAMDRhCwAAwNCELQAAAEMTtgAAAAxN2AIAADA0\nYQsAAMDQhC0AAABDE7YAAAAMTdgCAAAwNGELAADA0IQtAAAAQ9t1tg8AOLtWV1dbWVlZ/ry7dnXs\npZeWPu/utbWeO3p06fMCADAuYQvnuWPHjvXQwWeWPu/NV+7dtnkBAGAjtyIDAAAwNGELAADA0IQt\nAAAAQxO2AAAADE3YAgAAMDRhCwAAwNCELQAAAEMTtgAAAAxt19k+AICtWF1dbWVlZenz7l5b67mj\nR5c+LwAA20/YAkM5duxYDx18Zunz3nzl3qXPCQDAa8OtyAAAAAxN2AIAADA0YQsAAMDQhC0AAABD\nE7YAAAAMTdgCAAAwNGELAADA0IQtAAAAQxO2AAAADG3RsL2+Olg9Ud1+in3umr3/WHX1AmP/dPXr\n1bHqaxc/ZAAAAHjZImG7Wt3dFKhvrd5VvWXTPjdUl1dXVO+t7llg7Ker76h+6cwPHwAAgPPdImG7\nvzpUPVW9WD1Y3bRpnxurB2bPH612VxfPGXuw+s0zPnIAAABosbC9pHp6w/bh2WuL7LN3gbEAAABw\nxhYJ2+MLzrXyag4EAAAAzsSuBfY5Uu3bsL2v6crr6fa5dLbPBQuMPa0P339PF77+DVVdtf+63nbN\ndVsZDgAAwA6xvr7e+vr60uddJGw/0bQo1GXVM9U7mxaB2ujh6ramz9BeWz1fPVt9foGxdZqrvTe9\n532tXfSmBQ4TAACAnezAgQMdOHDgC9t33nnnUuZdJGxfaorWjzatcnxf9Xh16+z9e6tHmlZGPlS9\nUN0yZ2xNKyLfVf2+6l9Xn6ze8ap+GwAAAM47i4Rt1Udmj43u3bR92xbGVv2r2QPgrFtdXW1lZflL\nBexeW+u5o0eXPi8AAC9bNGwBzmnHjh3roYPPLH3em6/cu/Q5AQB4pUVWRQYAAIAdS9gCAAAwNGEL\nAADA0IQtAAAAQxO2AINZ27OnlZWVpT/W9uw5278aAMAZsSoywDbarq8RsoIzAMDLhC3ANtqOrxES\noAAAr+RWZAAAAIYmbAEAABiasAUAAGBowhYAAIChCVsAAACGJmwBAAAYmrAFAABgaMIWAACAoQlb\nAAAAhiZsAQAAGNqus30AAOwMq6urraysLH3e3WtrPXf06NLnBQA4QdgCUNWxY8d66OAzS5/35iv3\nLn1OAICN3IoMAADA0IQtAAAAQxO2AAAADE3YAgAAMDSLRwGwray2DABsN2ELwLay2jIAsN2ELQBD\n2o4rwa4CA8CYhC0AQ9qOK8GuAgPAmCweBQAAwNCELQAAAEMTtgAAAAxN2ALANlvbs6eVlZWlP9b2\n7DnbvxoA7AgWjwKAme36zt3KVx4BwDYStgAw4zt3AWBMbkUGAABgaMIWAACAoQlbAAAAhiZsAQAA\nGJqwBQAAYGjCFgAAgKH5uh8AGNR2fe/u7rW1njt6dOnzAsB2EbYAMKjt+t7d77xqn2AGYCjCFgB4\nhZGCWSwDUMIWAHiNbEcw33zl3qXOB8CYLB4FAADA0IQtAAAAQxO2AAAADE3YAgAAMDSLRwEAw/Jd\nvgCUsAUABrZdX01ktWWAsQhbAIBNXAkGGIuwBQDYxJVggLEIWwCA14grwQDbQ9gCALxGtutK8Hde\ntU8wA+c1YQsAMDi3TgPnO2ELAMBJbcet064CA9tB2AIAcFLbcSXYVWBgOwhbAABeMxbQAraDsAUA\n4DXj88DAdviSs30AAADwap24Erzsx9qePWf7V1vY2p495/3/DTh/uWILAMDwRrsSvLZnT88/99zS\n5/V1UpyvFgnb66sfr1arD1U/fJJ97qreUf3v6nurT84Zu6f6F9UfqJ6qvrN6/gyOHwAAts12fSa4\nlh+h2xXho/3RgPPTvLBdre6u3l4dqT5ePVw9vmGfG6rLqyuqa6p7qmvnjH1/9QvVj1S3z7bfv4xf\nCHaaX3v0V3rbNded7cOAV825zLnAecxW7dSoOxfOZQuJsUzzwnZ/dajpqmrVg9VNvTJsb6wemD1/\ntNpdXVx95WnG3lh98+z1B6r1hC3nqF//2Pj/xQPlXObc4DzmXHEunMvb9UcDt06fn+aF7SXV0xu2\nDzddlZ23zyXV3tOM/f3Vs7Pnz862AQAAXpWdepX9tbRdn+HeyXE/L2yPLzjPIn8SWTnFfMdP93N+\n4v3f3+u+9PcseBjz/b//+3+WNhcAAHB+2I5bp1d37erYSy8tdc4Tzre4n/f/mWurO5oWgar6QPW7\nvXIBqX/YdCvxg7Ptg023GX/lacYerA5Uv1V9efWL1ZUn+fmHqjcv9JsAAAAwmieb1mzaVrtmP+iy\n6nXVp6q3bNrnhuqR2fNrq19dYOyJRaNq+mzt31r6kQMAAMDMO6rfaLp6+oHZa7fOHifcPXv/sepr\n54yt6et+/m31m9XPNy04BQAAAAAAAMBOcH3T53Cf6OVblmEn2tf0GfFfr36t+v7Z63uavqv5ZHcl\nfKDp3D5Y/bHX7EhhMavVJ6ufm207lxnR7uqnm75i8L82fSuDc5nRfKDpf198uvrJ6ktzHjOG+5u+\n+ebTG147k3P362ZzPFH9vW083m2z2nTr8mXVBZ38c72wU1xcfc3s+Zc13Xr/lqbPkf/g7PXbe/lz\n5G9tOqcvaDrHD1Vf8hodKyziL1f/vHp4tu1cZkQPVO+ZPd9VvTHnMmO5rPpvTTFb9S+qd+c8Zgzf\nVF3dK8N2K+fuiQWOP1btnz1/pJcXJR7GN1b/ZsP2+2cPGMHPVm9v+ovTie9nvni2XdNfpDbehfBv\nmhZdg53g0qb1D76ll6/YOpcZzRubgmAz5zIj2dP0x/K1pj/O/Fz17TmPGcdlvTJst3rufnnTXTcn\nfFfTt/Gc0k78S84l1dMbtg/PXoOd7rKmv0492vQf3Gdnrz/by/9B3tt0Tp/g/GYn+bHqB5q+mu0E\n5zKj+crqt6t/XP3n6h9Vb8i5zFiOVn+3+mz1TPV8022czmNGtdVzd/PrR5pzTu/EsD1+tg8AzsCX\nVQ9Vf6H6X5veO97pz2vnPDvBn6w+1/T52lN9x7lzmRHsavqGhp+Y/ftCX3znl3OZne7N1V9s+qP5\n3qb/nfFnN+3jPGZU887dM7ITw/ZI04I8J+zrlbUOO80FTVH7z5puRa7pL1EXz55/eVMw1Bef35fO\nXoOz7bo+WDDbAAABNUlEQVTqxuoz1U9V39p0TjuXGc3h2ePjs+2fbgrc38q5zDi+vvqV6vPVS9XP\nNH1cz3nMqLbyvycOz16/dNPrw53Tu6onm/5C9bosHsXOtlL906ZbODf6kV7+vMD7++IPyL+u6Xa5\nJzv11TE4W765lz9j61xmRL9U/cHZ8zuazmPnMiP56qZvW7iw6Xx8oPrzOY8Zx2V98eJRWz13H21a\n1X6lQRePqnpH0wfmDzV9oBh2qj/S9HnETzXdwvnJpv/Q7WlahOdkS5r/1aZz+2D1x1/Lg4UFfXMv\nr4rsXGZEX910xfaxpitdb8y5zHh+sJe/7ueBpjvEnMeM4KeaPhv+O01rJ93SmZ27J77u51B117Yf\nNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwHb5/xxCqcpI4nUqAAAAAElFTkSuQmCC\n",
       "text": [
        "<matplotlib.figure.Figure at 0x108f55350>"
       ]
      }
     ],
     "prompt_number": 15
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Distribution of Log Transformed Target"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "log_targets = records.map(lambda r: np.log(float(r[-1]))).collect()\n",
      "hist(log_targets, bins=40, color='lightblue', normed=True)\n",
      "fig = matplotlib.pyplot.gcf()\n",
      "fig.set_size_inches(16, 10)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "iVBORw0KGgoAAAANSUhEUgAAA6YAAAJPCAYAAABvvskVAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAH0BJREFUeJzt3X+M5Hd93/HXMAtqbZp4p6G11lx0yLgspPwsvViYHxOw\nkJ22GGn/MFaiNJBQS60BqW3koErRnlqpIk0UlFqlF7ggmtI4hbOJk+Ia3HaERanto7ZpEi+ycU+1\nbw013CwFolb2sv3jOz7m1nv+zt7N7Xt35/GQRjcz3+/3s5/z6OCe9/l+v5MAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAsEtck2QlySNJbn6e/f5mkmeSLJ3DsQAAALClbpJHkxxM8sIkDyZ55Vn2+89J\n/jg/CtNJjwUAAGCGvaBl+6E0cXkiydNJbk1y3Rb7fSDJZ5M8dQ7HAgAAMMPawvSyJI+PvX5i9N7m\nfa5L8rHR641tHAsAAMCMawvTjZbtSfLRJL862rczekx6LAAAADNurmX7ySQHxl4fSLPyOe5vpDlN\nN0l+Ism1aU7dneTYXH755Rvf+MY3tjFlAAAA9pBvJHn58+3Qeb6NacL160nekWQ1yX1Jbkjy8Fn2\n/2SSP0py2zaO3djYsLg6q5aXl7O8vFw9DQr47Gebz392+exnm89/dvnsZ1un00la2rNtxfSZJDcl\nuSvNXXaPpgnLG0fbj5zDsQAAAHBaW5gmyZ2jx7izBel7JzgWAAAATmu7+RFcUP1+v3oKFPHZzzaf\n/+zy2c82n//s8tnTpu0a053gGlMAAIB9apJrTK2YAgAAUEqYAgDAJvO9XjqdztQf871e9W8NdiWn\n8gIAwCadTifHVlanPu7S4kL83ZdZ41ReAAAAdj1hCgAAQClhCgAAQClhCgAAQClhCgAAQClhCgAA\nQClhCgAAQClhCgAAQClhCgAAQClhCgAAQClhCgAAQClhCgAAQClhCgAAQClhCgAAQClhCgAAQClh\nCgAAQClhCgAAQClhCgAAQClhCgAAQKm56gkAAMC5mu/1sjYcVk8DOE/CFACAPWttOMyxldWpj7u0\nuDD1MYGzcyovAAAApYQpAAAApYQpAAAApYQpAAAApYQpAAAApYQpAAAApYQpAAAApYQpAAAApYQp\nAAAApYQpAAAApYQpAAAApYQpAAAApYQpAAAApYQpAAAApeaqJwAAALOi2+2m0+lMfdxL5uczPHVq\n6uPCThGmAACwQ9bX13NsZXXq4y4tLkx9TNhJTuUFAACglDAFAACglDAFAACglDAFAACglDAFAACg\nlDAFAACglDAFAACglDAFAACglDAFAACglDAFAACglDAFAACglDAFAACglDAFAACglDAFAACglDAF\nAACglDAFAACglDAFAACglDAFAACglDAFAACg1CRhek2SlSSPJLl5i+3XJXkoyQNJvprk7WPbTiT5\n2mjbfeczUQAAAPanuZbt3SS3JLk6yckk9ye5I8nDY/vcneQPR89fneT2JC8fvd5I0k9yajrTBQAA\nYL9pWzE9lOTRNCufTye5Nc0K6bgfjD1/cZJvb9reOY/5AQAAsM+1hellSR4fe/3E6L3N3p1mFfXO\nJB8ce38jzYrq8STvP/dpAgAAsF+1ncq7MeE4nxs93pLk95K8YvT+VUmeTPKSJF9Mc63qPdufJgAA\nAPtVW5ieTHJg7PWBNKumZ3PPaMy/nOQ7aaI0SZ5Kc+3poWwRpsvLy6ef9/v99Pv9lmkBAACwGw0G\ngwwGg20d03b951ySryd5R5LVNHfWvSFn3vzo8iSPpVldfUOSz4zeuyjNzZO+l+TiJF9Icnj067iN\njY1JF2YBAOBHOp1Ojq2sTn3cpcWFPTeuv1OzW3U6naSlPdtWTJ9JclOSu9JE5tE0UXrjaPuRJEtJ\nfiHNzZG+n+Q9o22XJrlt7Od8Os+NUgAAAGZcW5gmzQ2N7tz03pGx578+emz2WJLXneO8AAAAmBFt\nd+UFAACAC0qYAgAAUEqYAgAAUEqYAgAAUEqYAgAAUEqYAgAAUGqSr4sBAAB2sW63m06nM/VxL5mf\nz/DUqamPC5sJUwAA2OPW19dzbGV16uMuLS5MfUzYilN5AQAAKCVMAQAAKCVMAQAAKCVMAQAAKCVM\nAQAAKOWuvAAAXHDzvV7WhsPqaQC7lDAFAOCCWxsOfZ0JcFZO5QUAAKCUMAUAAKCUMAUAAKCUMAUA\nAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCU\nMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUA\nAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCU\nMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKCUMAUAAKDUXPUEAACA3anb7abT6Ux9\n3Evm5zM8dWrq47J3CVMAAGBL6+vrObayOvVxlxYXpj4me5tTeQEAACglTAEAACglTAEAACglTAEA\nACglTAEAACg1SZhek2QlySNJbt5i+3VJHkryQJKvJnn7No4FAABgxrV9XUw3yS1Jrk5yMsn9Se5I\n8vDYPncn+cPR81cnuT3Jyyc8FgAAgBnXtmJ6KMmjSU4keTrJrWlWSMf9YOz5i5N8exvHAgAAMOPa\nwvSyJI+PvX5i9N5m706zEnpnkg9u81gAAHaJ+V4vnU5n6g+A59N2Ku/GhON8bvR4S5LfS7K4nUks\nLy+fft7v99Pv97dzOAAAU7I2HObYyurUx11aXJj6mMDuNBgMMhgMtnVMW5ieTHJg7PWBNCufZ3PP\naMzeaL+Jjh0PUwAAAPauzYuNhw8fbj2m7VTe40muSHIwyYuSXJ/mBkbjLk/y7PkZbxj9+p0JjwUA\nAGDGta2YPpPkpiR3pbnL7tE015LeONp+JMlSkl9Ic4Oj7yd5T8uxAAAAcFpbmCbNDY3u3PTekbHn\nvz56THosAAAAnNZ2Ki8AAABcUMIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIU\nAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACA\nUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIU\nAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACA\nUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUsIUAACAUnPVEwAAYPvme72sDYfV\n0wCYCmEKALAHrQ2HObayOvVxlxYXpj4mQBun8gIAAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBK\nmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIA\nAFBqkjC9JslKkkeS3LzF9p9L8lCSryX5cpLXjG07MXr/gST3nc9EAQAA2J/mWrZ3k9yS5OokJ5Pc\nn+SOJA+P7fNYkrcm+W6aiP2dJFeOtm0k6Sc5NbUZAwAAsK+0rZgeSvJompXPp5PcmuS6Tft8JU2U\nJsm9SV66aXvn/KYIAADAftYWppcleXzs9ROj987ml5J8fuz1RpK7kxxP8v5zmSAAAAD7W9upvBvb\nGOtnkrwvyVVj712V5MkkL0nyxTTXqt6znQkCAACwv7WF6ckkB8ZeH0izarrZa5J8PM01psOx958c\n/fpUktvTnBr8nDBdXl4+/bzf76ff77dMCwAAgN1oMBhkMBhs65i2MD2e5IokB5OsJrk+yQ2b9vnJ\nJLcl+fk016M+66I0N0/6XpKLk7wzyeGtfsh4mAIAALB3bV5sPHx4yww8Q1uYPpPkpiR3pYnMo2nu\nyHvjaPuRJL+WZD7Jx0bvPZ1mZfTSNMH67M/5dJIvtM4IAACAmdIWpkly5+gx7sjY818ePTZ7LMnr\nznFeAAAAzIi2u/ICAADABSVMAQAAKCVMAQAAKDXJNaYAAABT0+120+l0pjrmJfPzGZ46NdUx2TnC\nFAAA2FHr6+s5trI61TGXFhemOh47y6m8AAAAlBKmAAAAlBKmAAAAlBKmAAAAlBKmAAAAlBKmAAAA\nlBKmAAAAlBKmAAAAlBKmAAAAlBKmAAAAlBKmAAAAlBKmAAAAlBKmAAAAlBKmAAAAlBKmAAAAlBKm\nAAAAlJqrngAAwH423+tlbTisngbAriZMAQAuoLXhMMdWVqc+7tLiwtTHBKjiVF4AAABKCVMAAABK\nCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMA\nAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABK\nCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMAAABKCVMA\nAABKCVMAAABKCVMAAABKCVMAAABKzVVPAAAA4Hx1u910Op2pj3vJ/HyGp05NfVzOJEwBAIA9b319\nPcdWVqc+7tLiwtTH5LmcygsAAEApYQoAAECpScL0miQrSR5JcvMW238uyUNJvpbky0les41jAQAA\nmHFtYdpNckuawHxVkhuSvHLTPo8leWuaIP2nSX5nG8cCAAAw49rC9FCSR5OcSPJ0kluTXLdpn68k\n+e7o+b1JXrqNYwEAAJhxbWF6WZLHx14/MXrvbH4pyefP8VgAAABmUNvXxWxsY6yfSfK+JFedw7EA\nAADMqLYwPZnkwNjrA2lWPjd7TZKPp7medLjNY7O8vHz6eb/fT7/fb5kWAAAAu9FgMMhgMNjWMW1h\nejzJFUkOJllNcn2amxiN+8kktyX5+TTXlG7n2CRnhikAAAB71+bFxsOHD7ce0xamzyS5Kcldae6y\nezTJw0luHG0/kuTXkswn+djovafT3PjobMcCAADAaW1hmiR3jh7jjow9/+XRY9JjAQAA4LS2u/IC\nAADABSVMAQAAKCVMAQAAKCVMAQAAKCVMAQAAKCVMAQAAKCVMAQAAKDXJ95gCAOx7871e1obD6mkA\nzCRhCgCQZG04zLGV1amPu7S4MPUxAfYbp/ICAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgC\nAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQ\nSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgC\nAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQSpgCAABQ\naq56AgAA2zHf62VtOKyeBgBTJEwBgD1lbTjMsZXVqY+7tLgw9TEBmIxTeQEAACglTAEAACglTAEA\nACglTAEAACglTAEAACglTAEAACglTAEAACglTAEAACglTAEAACglTAEAACglTAEAACglTAEAACgl\nTAEAACglTAEAACglTAEAACglTAEAACg1SZhek2QlySNJbt5i+2KSryT5v0n+0aZtJ5J8LckDSe47\n51kCAACwb821bO8muSXJ1UlOJrk/yR1JHh7b5ztJPpDk3Vscv5Gkn+TU+U4UANhb5nu9rA2H1dMA\nYA9oC9NDSR5Ns/KZJLcmuS5nhulTo8ffOssYnfOYHwCwR60Nhzm2sjr1cZcWF6Y+JgC12k7lvSzJ\n42Ovnxi9N6mNJHcnOZ7k/dubGgAAALOgbcV04zzHvyrJk0lekuSLaa5Vvec8xwQAAGAfaQvTk0kO\njL0+kGbVdFJPjn59KsntaU4Nfk6YLi8vn37e7/fT7/e38SMAAADYLQaDQQaDwbaOaQvT40muSHIw\n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\neSrJ7WlODX5OmP7Bv/yN089/6tCb8td/+k1t8wYAAGAXGgwGGQwG2zqmLUyPp7mp0cE0kXl9khs2\n7XNHkpvSXH96ZZK1NNeXXpTm5knfS3JxkncmObzVD7n+A/94W5MGAABgd+r3++n3+6dfHz68ZQae\noS1Mn0kTnXelicyjaW58dONo+5Ekn09zZ95Hk/wgyXtH2y5NctvYz/l0ki+0zggAAICZMsn3mN45\neow7sun1TVsc91iS153LpAAAAJgdbXflBQAAgAtKmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIA\nAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBKmAIAAFBK\nmAIAAFBqrnoCAAAATEe3202n05n6uJfMz2d46tTUx32WMAUAANgn1tfXc2xlderjLi0uTH3McU7l\nBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAA\noJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQw\nBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAA\noJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQw\nBQAAoJQwBQAAoJQwBQAAoJQwBQAAoJQwBQAAoNQkYXpNkpUkjyS5+Sz7/PZo+0NJXr/NYwEAAJhh\nbWHaTXJLmsB8VZIbkrxy0z4/m+TlSa5I8veSfGwbxzLjBoNB9RQo8if3/tfqKVDI5z+7fPazzec/\nu3z2tGkL00NJHk1yIsnTSW5Nct2mfd6V5FOj5/cmuSTJpRMey4wTprPrT+/zf1CzzOc/u3z2s83n\nP7t89rRpC9PLkjw+9vqJ0XuT7LMwwbEAAADMuLmW7RsTjtM5n0n8i7//i+dz+HN8+1tP5g2v/qmp\njgkAAMCF0RaUVyZZTnOdaJJ8OMkPk3xkbJ9/nWSQ5lTdpLnZ0duSvGyCY5PmdN/LtztxAAAA9oRv\npLkv0TmbGw1yMMmLkjyYrW9+9PnR8yuT/LdtHAsAAACtrk3y9TQrmx8evXfj6PGsW0bbH0ryhpZj\nAQAAAAAAAEia609XkjyS5ObiubCzfjfJt5L8j+qJsOMOJPkvSf40yZ8k+WDtdNhBfyHN14o9mOTP\nkvzz2ulQpJvkgSR/VD0RdtyJJF9L8/nfVzsVdtglST6b5OE0//t/Ze102EGvSPNn/tnHd7ML/+7X\nTXOK78EkL4xrUGfNW5K8PsJ0Fl2a5HWj5y9Oc7q/P/uz46LRr3Np7knw5sK5UOMfJvl0kjuqJ8KO\n+59JetWToMSnkrxv9HwuyY8XzoU6L0jyZJpFii03VjmUJkxPJHk6zV19ryucDzvrniTD6klQ4ptp\n/iEqSb6f5l9PF+qmww7789GvL0rzD5SnCufCzntpmpsmfiLn+VVz7Fk+99nz42kWJH539PqZNKtm\nzJ6r09wc9/GtNlaG6WU5c1JPjN4DZsfBNCvn9xbPg53zgjT/MPGtNKd0/1ntdNhhv5XkV9J8fRyz\nZyPJ3UmOJ3l/8VzYOS9L8lSSTyb570k+nh+dPcNseU+Sf3e2jZVhulH4s4F6L05zvcmH0qycMht+\nmOZU7pcmeWuSfuls2El/O8n/TnONkVWz2XRVmn+MvDbJP0izisb+N5fmWzv+1ejXHyT51dIZUeFF\nSf5Oks+cbYfKMD2ZM88vPpBm1RTY/16Y5FiSf5vkc8VzocZ3k/yHJG+sngg75k1J3pXmOsPfT/L2\nJP+mdEbstCdHvz6V5PY0l3Wx/z0xetw/ev3ZnPn1ksyGa5N8Nc2f/11nLs05xgfTFLSbH82eg3Hz\no1nUSfOX0d+qngg77ifS3JkxSf5iki8leUfddCj0trgr76y5KMlfGj2/OMmXk7yzbjrssC8l+Wuj\n58tJPlI3FYrcmuTvVk/i+Vyb5o6cjyb5cPFc2Fm/n2Q1yf9Lc63xe2unww56c5rTOR/Mj24dfk3p\njNgpr05zfdGDab4y4ldqp0Oht8VdeWfNy9L82X8wzVeF+XvfbHltmhXTh5LcFnflnTUXJ/l2fvSP\nUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsPP+P561aMtampliAAAAAElFTkSuQmCC\n",
       "text": [
        "<matplotlib.figure.Figure at 0x108f28d10>"
       ]
      }
     ],
     "prompt_number": 16
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Distribution of Square-root Transformed target"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "sqrt_targets = records.map(lambda r: np.sqrt(float(r[-1]))).collect()\n",
      "hist(sqrt_targets, bins=40, color='lightblue', normed=True)\n",
      "fig = matplotlib.pyplot.gcf()\n",
      "fig.set_size_inches(16, 10)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "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\nkvxJkqfT3DPd/r/49tr2iX2/L77e/vmONAenRrHv98lu2z+Zcf+fZ6Rem+T5idcv5I0fXvTDxSSf\nTvJ4kh+d81w4eNekOQU07Z/XzHEuzMePpbng3gNxylcfnEhzRP2x2P/75kSabf/aHSDs+/3wtjS/\nqHgpb5z6bd/vj922f3II9v9TSX524vUPJ/kPc5oL8/He9s/vTvM/4u+b41y4+k7kzad77jyytn1w\nU2EOTuTN2//Ppvlt6iDJv0rzf1Ysrncn+Z9546iJ/b8/3p3ml9GvbXv7fv98Z5pfUHx/7Pt99Nr2\nX80+9v95Hkl9Mc2X6l9zPM3RVPrjj9o/v5bkU2lOAac/XkrznaWk+YXFV+c4Fw7eV9OcTXExyc/F\n/r/I3p5kPckvJfn1dpn9vx9e2/a/nDe2vX2/f/44yW8m+Uux7/fRa9v/e7KP/X+ekfp4kuvT/Hb9\nHUnuSHJujvPhYL0ryZ9qn39Hkh/Km4+ysPjOJfmR9vmP5I3/gKEf3jvx/G/H/r+oBml+U/5Ukp+e\nWG7/X3x7bXv7fj98V944lfPbk/xgmqu52vf7Ya/t/56JdUrv/x9Nc7W380k+Mee5cLDel+YU3yfS\nXJre9l9sv5pkK8n/S/Nd9LvSXNn503EZ+j7Yuf0/luQX09yC6sk0/5Hie0mL6cNJvpXmZ/3kLQfs\n/4tvt23/0dj3++IvJPn9NNv/C0l+sl1u3++Hvba//R8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAgP75/1PBPDr+HxiyAAAAAElFTkSuQmCC\n",
       "text": [
        "<matplotlib.figure.Figure at 0x109f26150>"
       ]
      }
     ],
     "prompt_number": 17
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Impact of Training on Log Transformed Targets"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# train a linear model on log-transformed targets\n",
      "data_log = data.map(lambda lp: LabeledPoint(np.log(lp.label), lp.features))\n",
      "model_log = LinearRegressionWithSGD.train(data_log, iterations=10, step=0.1)\n",
      "\n",
      "true_vs_predicted_log = data_log.map(lambda p: (np.exp(p.label), np.exp(model_log.predict(p.features))))\n",
      "\n",
      "mse_log = true_vs_predicted_log.map(lambda (t, p): squared_error(t, p)).mean()\n",
      "mae_log = true_vs_predicted_log.map(lambda (t, p): abs_error(t, p)).mean()\n",
      "rmsle_log = np.sqrt(true_vs_predicted_log.map(lambda (t, p): squared_log_error(t, p)).mean())\n",
      "print \"Mean Squared Error: %2.4f\" % mse_log\n",
      "print \"Mean Absolute Error: %2.4f\" % mae_log\n",
      "print \"Root Mean Squared Log Error: %2.4f\" % rmsle_log\n",
      "print \"Non log-transformed predictions:\\n\" + str(true_vs_predicted.take(3))\n",
      "print \"Log-transformed predictions:\\n\" + str(true_vs_predicted_log.take(3))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Mean Squared Error: 38606.0875\n",
        "Mean Absolute Error: 135.2726\n",
        "Root Mean Squared Log Error: 1.3516\n",
        "Non log-transformed predictions:\n",
        "[(16.0, 119.30920003093597), (40.0, 116.95463511937379), (32.0, 116.5729461064775)]\n",
        "Log-transformed predictions:\n",
        "[(15.999999999999998, 45.860944832109993), (40.0, 43.255903592233274), (32.0, 42.311306147884252)]\n"
       ]
      }
     ],
     "prompt_number": 18
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# train a decision tree model on log-transformed targets\n",
      "data_dt_log = data_dt.map(lambda lp: LabeledPoint(np.log(lp.label), lp.features))\n",
      "dt_model_log = DecisionTree.trainRegressor(data_dt_log, {})\n",
      "\n",
      "preds_log = dt_model_log.predict(data_dt_log.map(lambda p: p.features))\n",
      "actual_log = data_dt_log.map(lambda p: p.label)\n",
      "true_vs_predicted_dt_log = actual_log.zip(preds_log).map(lambda (t, p): (np.exp(t), np.exp(p)))\n",
      "\n",
      "mse_log_dt = true_vs_predicted_dt_log.map(lambda (t, p): squared_error(t, p)).mean()\n",
      "mae_log_dt = true_vs_predicted_dt_log.map(lambda (t, p): abs_error(t, p)).mean()\n",
      "rmsle_log_dt = np.sqrt(true_vs_predicted_dt_log.map(lambda (t, p): squared_log_error(t, p)).mean())\n",
      "print \"Mean Squared Error: %2.4f\" % mse_log_dt\n",
      "print \"Mean Absolute Error: %2.4f\" % mae_log_dt\n",
      "print \"Root Mean Squared Log Error: %2.4f\" % rmsle_log_dt\n",
      "print \"Non log-transformed predictions:\\n\" + str(true_vs_predicted_dt.take(3))\n",
      "print \"Log-transformed predictions:\\n\" + str(true_vs_predicted_dt_log.take(3))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Mean Squared Error: 14781.5760\n",
        "Mean Absolute Error: 76.4131\n",
        "Root Mean Squared Log Error: 0.6406\n",
        "Non log-transformed predictions:\n",
        "[(16.0, 54.913223140495866), (40.0, 54.913223140495866), (32.0, 53.171052631578945)]"
       ]
      },
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "\n",
        "Log-transformed predictions:\n",
        "[(15.999999999999998, 37.530779787154508), (40.0, 37.530779787154508), (32.0, 7.2797070993907287)]"
       ]
      },
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "\n"
       ]
      }
     ],
     "prompt_number": 19
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "# Cross-validation\n",
      "## Creating Training and Test Sets"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# create training and testing sets for linear model\n",
      "data_with_idx = data.zipWithIndex().map(lambda (k, v): (v, k))\n",
      "test = data_with_idx.sample(False, 0.2, 42)\n",
      "train = data_with_idx.subtractByKey(test)\n",
      "\n",
      "train_data = train.map(lambda (idx, p): p)\n",
      "test_data = test.map(lambda (idx, p) : p)\n",
      "\n",
      "train_size = train_data.count()\n",
      "test_size = test_data.count()\n",
      "print \"Training data size: %d\" % train_size\n",
      "print \"Test data size: %d\" % test_size\n",
      "print \"Total data size: %d \" % num_data\n",
      "print \"Train + Test size : %d\" % (train_size + test_size)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Training data size: 13934\n",
        "Test data size: 3445\n",
        "Total data size: 17379 \n",
        "Train + Test size : 17379\n"
       ]
      }
     ],
     "prompt_number": 20
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# create training and testing sets for decision tree\n",
      "data_with_idx_dt = data_dt.zipWithIndex().map(lambda (k, v): (v, k))\n",
      "test_dt = data_with_idx_dt.sample(False, 0.2, 42)\n",
      "train_dt = data_with_idx_dt.subtractByKey(test_dt)\n",
      "\n",
      "train_data_dt = train_dt.map(lambda (idx, p): p)\n",
      "test_data_dt = test_dt.map(lambda (idx, p) : p)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 21
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Evaluating the Impact of Different Parameter Settings for Linear Model"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# create a function to evaluate linear model\n",
      "def evaluate(train, test, iterations, step, regParam, regType, intercept):\n",
      "    model = LinearRegressionWithSGD.train(train, iterations, step, regParam=regParam, regType=regType, intercept=intercept)\n",
      "    tp = test.map(lambda p: (p.label, model.predict(p.features)))\n",
      "    rmsle = np.sqrt(tp.map(lambda (t, p): squared_log_error(t, p)).mean())\n",
      "    return rmsle"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 22
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### Iterations"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "params = [1, 5, 10, 20, 50, 100]\n",
      "metrics = [evaluate(train_data, test_data, param, 0.01, 0.0, 'l2', False) for param in params]\n",
      "print params\n",
      "print metrics\n",
      "plot(params, metrics)\n",
      "fig = matplotlib.pyplot.gcf()\n",
      "pyplot.xscale('log')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[1, 5, 10, 20, 50, 100]\n",
        "[2.3532904530306888, 1.6438528499254725, 1.4869656275309227, 1.4149741941240344, 1.4159641262731957, 1.4539667094611681]\n"
       ]
      },
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "iVBORw0KGgoAAAANSUhEUgAAAXkAAAEFCAYAAAAG45eHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGKVJREFUeJzt3XmUlNWZx/FvC6gxaIxxQRbTirgRZBUJuJTbuIyi4Axu\nGJcZo2YwJJmMcYyR9kQFnRGJQoCgEIgJOJEWBbdjoiUqoBEFWaPiLrIIDgygINDzx+2WpumG6u6q\nurV8P+fUoal6+60f+vL0w6373guSJEmSJEmSJEmSJEmSJEmqoQ3wPLAAmA/8eCfHHgdsBvpmIZck\nKQ1aAJ0qv24O/B04upbjmgDPAdOAC7MTTZK0K7vt4vVlwJzKr9cBi4CWtRx3A/AIsDJ90SRJ2VQK\nfEDo6KtrRRjSKQHG4XCNJOWMXXXyVZoTOvWBhI6+umHATUAFodCXpC2dJKlRUinIzQhj7U8RCnpN\n71Y7z/7ABuAa4PHqB7Vt27ZiyZIlDU8qScVpCXB4pk5eAkwA7k3x+J0N11QUgkGDBhXM+zb2nA35\n/vp8T6rHpnLczo6J9f80E2L8WYrx2kz1+HQcQxglabCmu3i9F9AfeBN4o/K5m4FDKr8e3Zg3z0eJ\nRKJg3rex52zI99fne1I9NpXjYv1/y7YYf85ivDZTPT4Xrs1sjp9X/lCScktZWRllZWWxY0i1Kikp\ngUbU6lQ/eJUKVrF0+SpOdvKSlMPs5CVJdbLIS1IBs8hLUgGzyEtSActqkfdzV0nKrqwW+VGjsvlu\nkqSsTqHcf/8K/vIX6Ngxi+8qSXksr6ZQ3nsvXHQRrKu5jqUkKSOyfjPUVVeFsfnf/z6L7yxJeSqv\nOnmA4cPhlVfgD3/I9jtLUvGJsqzBvHlw6qnw0ktw5JFZTCBJeSbvOnmADh3g9tuhXz/48ssYCSSp\nOERboKyiInwIe8ABMGJEFlNIUh7Jy04eoKQExoyBp56CyZNjpZCkwhZ9qeFXX4Vzzw2/lpZmMY0k\n5YG87eSrdO8ON90El1wCX30VO40kFZbonXx4Ac47D9q3h7vuymIiScpxje3kc6LIA3z2GXTuDL/7\nHZx9dhZTSVIOK5giDzB9ephxM3s2tGyZpVSSlMPyfky+upNOguuvh/79YcuW2GkkKf/lVJEH+OUv\nw6933BE3hyQVgpwarqmydCl07QqTJsHJJ2c4lSTlsIIarqnSsiWMGxeGbVaujJ1GkvJXTnbyVX7x\nC5g/H6ZOhd1y8seRJGVWQXbyVW6/HVavDpuNSJLqL6c7eYD33w93xU6bFn6VpGJS0J08hPVsRo2C\niy+GNWtip5Gk/JLznXyVAQNgxQp4+OGwgqUkFYOC7+Sr/Pd/w9tvh2UPJEmpyZtOHuCtt6BXL/jr\nX+HYY9OUSpJyWNF08gBHHAFDh4b1bdavj51GknJfXnXyVa68MozLjxuXltNJUs4qqk6+yvDhMHMm\nPPRQ7CSSlNvyspMHePNNOO00ePnlMIwjSYUoG518G+B5YAEwH/hxLcdcBswF3gReBjL+seixx8Kv\nfx3G57/8MtPvJkn5KZWfDi0qH3OA5sBs4AJgUbVjvg8sBNYAZwFlQI8a50lrJx9OCP36wUEHhSEc\nSSo02ejklxEKPMA6QnGvuW/TTEKBB3gFaN3QQPVRUgJjxsCTT0J5eTbeUZLyS30/eC0FOhMKeV3+\nBXiyoYHqa999w7rz110X1rmRJG3TtB7HNgceAQYSOvranAJcDfSq7cWysrKvv04kEiQSiXq8fd26\nd4cbb4RLLgn7xDZrlpbTSlLWJZNJkslk2s6X6jhPM2Aa8BQwrI5jjgXKCWPy79TyetrH5KvbuhXO\nPTd8IDtkSMbeRpKyqrFj8ql8YwkwHlgF/LSOYw4BngP6A7PqOCajRR7CLlJdusADD8CZZ2b0rSQp\nK7JR5E8AphOmR1ZV6ZsJhR1gNPAA0Af4sPK5r4Caq79nvMgDvPBCWJZ49uywjaAk5bNsFPl0yUqR\nB7jttlDsn30WmjTJyltKUkYU5bIGu3LLLWEO/Z13xk4iSXEVZCcPsHQpdO0aNhk56aSsva0kpZWd\nfB1atoSxY+Gyy+Czz2KnkaQ4CraTr3LjjbBwIUyd6raBkvKPnfwu3HFH6OTvvTd2EknKvoLv5CEs\nd9C9OzzxBBx3XJQIktQgdvIpKC2FkSPD/Pk1a3Z5uCQVjKLo5Kv86EewalVY0MzxeUn5wE6+HoYO\nhcWLw/LEklQMiqqTh1DkTzwRnnsOOnSInUaSds5Ovp6OOgruuSfsKLV+few0kpRZRdfJV7niirCu\nzdixsZNIUt3s5BtoxAiYMQP++MfYSSQpc4q2kweYOxdOPz0U+3btYqeRpB3ZyTdCx45hWeJ+/eDL\nL2OnkaT0K+pOHsKSxP/8z3DwwXD//bHTSNL27OQbqaQkbBc4bRo8+mjsNJKUXkXfyVd55RXo3Rte\nfRW++93YaSQpsJNPk+OPh5//HC65BL76KnYaSUoPO/lqtm6Fc88NH8gOHhw7jSS5kXfarVwJnTvD\ngw/CmWfGTiOp2FnkMyCZDMM2r78eZt1IUiyOyWdAIgHXXgv9+8OWLbHTSFLDWeTr8KtfhQLv2Lyk\nfOZwzU588gl07Qp//nNYnliSss3hmgxq1SqsUnnZZWFHKUnKN3byKfj5z+Hvf4fHH3fbQEnZZSef\nBXfeCStWwLBhsZNIUv3YyafovffCXbFPPgndusVOI6lY2MlnyaGHwm9/CxddBGvWxE4jSamxk6+n\n66+Hzz+HiRMdn5eUeXbyWTZ0KCxaFJYnlqRcZyffAIsXh3nzzz8P3/te7DSSCpmdfARHHQX/9V9h\n28D162OnkaS62ck3UEUFXHEFNGsWVqyUpEzIdCffBngeWADMB35cx3H3AW8Dc4HODQ2TT0pKwmyb\nl16CP/0pdhpJqt2ufjq0qHzMAZoDs4ELgEXVjjkHGFD56/HAb4AetZyroDr5KnPmwBlnwIwZ0K5d\n7DSSCk2mO/llhAIPsI5Q3FvWOKY3ML7y61eAfYGDGhoo33TqBGVlcPHFsHFj7DSStL36fPBaShiK\neaXG862Aj6r9/mOgdeNi5Zcf/Shs/n3jjbGTSNL2Ui3yzYFHgIGEjr6mmv+UKLxxmZ0oKQkfvj72\nGEyZEjuNJG3TNIVjmgGTgYeA2krYJ4QPaKu0rnxuB2VlZV9/nUgkSCQSKcbMfd/+NkyaBOefD126\nwCGHxE4kKR8lk0mSyWTazrerwfwSwnj7KuCndRxT/YPXHsAwiuiD15ruvjt09MlkmF4pSY2R6Y28\nTwCmA2+ybQjmZqCqTx1d+etw4CxgPXAV8Hot5yqKIr91K5xzTujm77wzdhpJ+S7TRT6diqLIQ1h7\nvksXGDcuTK+UpIZyWYMcdOCBMGFCuCN22bLYaSQVM4t8hpx6Kvzrv0L//rBlS+w0koqVRT6Dbr0V\nvvoKhgyJnURSsXJMPsM++QS6doVHHoETToidRlK+cUw+x7VqFW6UuvRSWLUqdhpJxcZOPkv+/d/h\nnXfCHbFuGygpVXbyeWLwYPj0U7jvvthJJBUTO/ksevddOP54eOop6NYtdhpJ+cBOPo8cdhiMGBGW\nJV67NnYaScXATj6C666DNWvCjlKOz0vaGTv5PHTvvbBggXvDSso8O/lIFi2Ck04Kq1W2bx87jaRc\nZSefp44+OixL3K8fbNgQO42kQmUnH1FFBVx+Oey5JzzwQOw0knKRnXweKymBkSNh+nSYODF2GkmF\nyE4+B8yZE9adnzkTDj88dhpJucROvgB06gSDBsFFF8HGjbHTSCokdvI5oqICLrwwbAA+bFjsNJJy\nhZ18gSgpCfPmp0wJG4FLUjrYyeeYGTOgTx/4299CVy+puNnJF5iePeFnPwvrz2/eHDuNpHxnJ5+D\ntm6Fc84JO0rdcUfsNJJiamwnb5HPUStWQOfOMH48nH567DSSYnG4pkAdeCBMmAA/+AEsWxY7jaR8\nZSef4371K5g1C555BnbzR7JUdOzkC9ygQeEGqSFDYieRlI/s5PPAxx+H7QInT4ZevWKnkZRNdvJF\noHXrsErlpZfC6tWx00jKJ3byeeRnP4MlS8JdsW4bKBUHO/kiMmQILF0K998fO4mkfGEnn2eWLIEe\nPeDpp8PNUpIKm518kWnbFoYPD8sSr10bO42kXGcnn6d++ENYtw7++EfH56VCZidfpIYNg3nzYOzY\n2Ekk5TI7+Ty2cCGcfDIkk9C+few0kjLBTr6IHXMM3HVXGJ/fsCF2Gkm5KJUiPxZYDsyr4/X9gaeB\nOcB84Mq0JFNKrroKOnaEgQNjJ5GUi1Ip8uOAs3by+gDgDaATkADuAZo2OplSUlICo0aFIZtJk2Kn\nkZRrUinyLwKf7+T1T4F9Kr/eB1gFuKdRFu29Nzz8MNxwA7zzTuw0knJJOsbkxwDtgaXAXMCBgwi6\ndIFbb4WLLw6rVkoSpKfI30wYj29JGLIZAeydhvOqngYMgDZt4KabYieRlCvSMXbeE6jaiXQJ8B5w\nJPBazQPLysq+/jqRSJBIJNLw9qpSUgIPPhi2DTzlFOjdO3YiSfWVTCZJJpNpO1+qcy9LgalAh1pe\nGwqsAW4DDgJmA8cCNRfFdZ58lsyYAX36wGuvhc5eUv7KxkbeE4GTCVMllwODgGaVr42ufH4ccAhh\n+Gcw8KdazmORz6LBg+GJJ8Ksm6bOdZLyVjaKfLpY5LNo61Y46yzo3h1uvz12GkkNZZFXnZYvD7Nu\nxo+H00+PnUZSQ7isgep00EEwYQJccUUo+JKKj518EbjlFnj11bDRyG7+WJfyip28dqmsDL74Iixm\nJqm42MkXiY8+gm7doLwcevWKnUZSquzklZI2bWDMGLj0Ulhd8w4GSQXLTr7I/PSn8P77oaN320Ap\n99nJq16GDAlDN8OHx04iKRvs5IvQkiXQowc880yYRy8pd9nJq97atoX77w/bBv7f/8VOIymT7OSL\n2DXXhL1hH3rI8XkpV9nJq8F+8xuYOxfGjYudRFKm2MkXuQULIJGAF16AY46JnUZSTXbyapT27cOM\nm4suCnfFSiosdvKiogIuuyxsCD56dOw0kqqzk1ejlZTAqFHw3HPw8MOx00hKJzt5fW327LDRyKxZ\nYZqlpPjs5JU2XbuGZYkvvhg2bYqdRlI62MlrOxUVcMEFoZMfOjR2Gklu/6e0W70aOncO69ucd17s\nNFJxs8grI15+Gfr2hddeC8sUS4rDMXllRK9eMHBgWH9+8+bYaSQ1lEVedbrpJthzT7jttthJJDWU\nwzXaqWXLwnLEf/gDnHZa7DRS8XG4RhnVogVMmAA/+AEsXx47jaT6spNXSn75y/Ah7FNPwW62BlLW\n2MkrK267Ddavh7vvjp1EUn3YyStlH34Ixx0Hjz4KPXvGTiMVBzt5Zc0hh8CYMWFa5erVsdNISoWd\nvOpt4MDQ1ZeXu22glGne8aqs27gRTjgBvvc9uO++sA69pMxwuEZZt8ceYe35pk2hY0d46aXYiSTV\nxU5ejfL443DttXDllWEGzu67x04kFRY7eUXVuzfMnQsLF0L37jB/fuxEkqqzyKvRDjwQpkyBG26A\nU04J69Bv3Ro7lSRwuEZp9u67YQmE3XeH3/8+TLuU1HDZGK4ZCywH5u3kmATwBjAfSDY0jPLfYYfB\nCy/AP/wDdOsGDz0UdpuSFEcqPx1OBNYBE4AOtby+L/AycCbwMbA/8Fktx9nJF5k33oD+/aF9exg5\nEr7zndiJpPyTjU7+ReDznbx+KTCZUOCh9gKvItS5M8yeDa1bh6mWzzwTO5FUfNLxwWs7YD/geeA1\n4PI0nFMFYs89wwex48fDNdfAgAGwYUPsVFLxaJqGczQDugCnAXsBM4FZwNs1DywrK/v660QiQSKR\nSMPbKx+cdhq8+WYo8p07h01IunePnUrKPclkkmQymbbzpTrOUwpMpfYx+V8A3wDKKn//APA08EiN\n4xyTFwD/8z9huuW//RvcfHO4c1ZS7XLhZqjHgBOAJoRO/nhgYRrOqwLVrx+8/jq8/HLYMPytt2In\nkgpXKkV+IjADOBL4CLgauLbyAbCY0Lm/CbwCjMEir11o1QqefjrMqe/ZM8y+8R96Uvp5M5SiW7wY\nLr8cDjgAHnwQDj44diIpd+TCcI3UKEcdBTNmhF2nOnWCyZNjJ5IKh528csqsWaGr79kzrFX/rW/F\nTiTFZSevgtKjB8yZA3vtFW6gSuNMMqko2ckrZz35ZLiB6pJL4Pbbw41VUrGxk1fBOuecsFb9e++F\n8fq5c2MnkvKPRV45bf/94ZFH4D/+A04/He6+G7ZsiZ1Kyh8O1yhvfPBBmFdfURHWwjn00NiJpMxz\nuEZF47vfDRuI9+4d1r0ZN84bqKRdsZNXXpo3L6xV37YtjB4dbqSSCpGdvIpShw7w6qvQrl2Yajlt\nWuxEUm6yk1femz4drrgibDl4zz3QvHnsRFL62Mmr6J10UpheuWlTWBZh5szYiaTcYSevgvLoo3D9\n9eEmqltvhWbNYieSGsdOXqqmT5+wLMIbb8D3vw+LFsVOJMVlkVfBadECpk6FH/4wDOXcdx9s3Ro7\nlRSHwzUqaO+8E1a1bN48zKtv3Tp2Iql+HK6RduLww+HFF+Hkk6FLF5g0KXYiKbvs5FU0XnstdPWd\nO8OIEfDtb8dOJO2anbyUom7dYPbssOhZx47wl7/ETiRlnp28itKzz8LVV8OFF8LgwfCNb8ROJNXO\nTl5qgDPOCDdQLV8e1r+54Yaw+NnmzbGTSellJ6+it3hxuImqvDxsUHLeedC3b/hB4G5Uiq2xnbxF\nXqrmww9hypRQ8OfMCevh9O0bdqnaZ5/Y6VSMLPJShqxcCY8/Hgr+iy/CiSeGgt+7t0sbK3ss8lIW\nrF0bNhYvL4dnngnTMPv2DcsotGkTO50KmUVeyrIvvgjTL8vLw/IJhx66reAfdVTsdCo0Fnkpos2b\nw3r25eXhw9tvfWtbwe/SBUqy+TdMBckiL+WIrVvhb38LBb+8PKxv36dPKPq9ekGTJrETKh+sXAkL\nFmx7jBxpkZdyTkVF+Ata1eEvXQrnnx+K/qmnwh57xE6o2Fat2r6YVz02bYL27bc9fvITi7yU8959\nNxT7Rx8Nf5HPPjt0+Ged5XaFhe5//3fHQj5/PmzYsH0xr3q0bLn9MJ/DNVKe+fRTeOyxUPBnzoRT\nTgkF/7zzYL/9YqdTQ61dW3tnvnYtHHPMjsW8devUPrOxyEt57PPP4YknwrDOX/8Kxx0XCv4FF4SO\nTrln3TpYuHDHYr5qFRx99I7F/JBDYLdGLCBjkZcKxIYNYQ5+eXko/EceuW2mzuGHx05XfNavD9tH\n1izmK1aEqbI1i3lpaeOKeV0s8lIB2rQJkslQ8KdMgQMP3Fbwjz3WqZnp9MUXYf2imsV86VI44ogd\ni/lhh2V3ppRFXipwW7bArFnbpmbuttu2gt+jR2a6x0K0cWPtxfzjj8O/lGoW87ZtoWnT2KmzU+TH\nAv8IrAA67OS444CZQD+gvJbXLfJSI1VUhCWSq6ZmrloVpmb27QuJBDRrFj9f9Udtz2XjtTVrdizm\nH3wQ7k6uWczbtYv/321nslHkTwTWAROou8g3AZ4FNgDjgMm1HGORV05KJpMkEonYMRrkrbe2Tc1c\nuHDbdMwYhbW6kpLtH7U9t7PnG/va3nvvOKPliCNg993T+98/G7I1XFMKTKXuIv8TYBOhm5+GRV55\npKysjLKystgxGm316jC+nOkCuqvXlF65sDNUK+B8YGTl7wu6kieTyYJ538aesyHfX5/vSfXYVI6L\n9f8tm/bbD95+O0nLlnDwweHRogUcdFD44PaAA8L+tt/5Tnjst1/YzHzffcOaO/vsEzrgvfcO/yL4\n5jdhr73C1oh77hnu0t1jj9ANN2sWxqubNIHp05PbFfp0yPVrM9Xjc+HaTEeRHwbcRCjuJWT3w9ys\ns8g37vst8pkV489ZjNdmqsfnwrWZjuGad6udZ3/CuPw1wOM1jnsHaFv/iJJU1JYAGb9TohSYl8Jx\n44C+mY0iSUpVKrNAJwInE7r0j4BBQNWEo9EZyiVJkiRJkiRJktLjm8B44HfApZGzSDUdCjwA/Dl2\nEKmG8wl1cxJwRuQsO3U5YT0cCGGlXGSRV67al9CI7FI6168bCyxnx6mWZwGLgbeBX1Q+14owUwdg\nSxozSHWpz/UpZVNDrs1bgOGZj7a9E4HObB+0CeEmqFLCtMs5wNFAf7Z18hOzF1FFrD7XZxU7eWVD\nfa7NEuAu4LRUT57OTv5F4PMaz3UnBH0f+IowNHM+YSniC4HfsuOdsVIm1Of63A8YBXTC7l6ZV59r\ncwChwP8TcG0qJ8/0kvjVh2UAPgaOJyx9cHWG31valbquz9XAdVESSUFd1+YNwP31OVGm95Qp6BUp\nlfe8PpWr0nZtZrrIfwK0qfb7NoSfSFIu8PpUrsrZa7OU7T88aEpYQa0U2J0dP9iSsqkUr0/lplLy\n4NqcCCwFNhLGkq6qfP5s4O+EDxH+M040yetTOctrU5IkSZIkSZIkSZIkSZIkSZIkSZIkSQXs/wFH\nGwwS2EtbVQAAAABJRU5ErkJggg==\n",
       "text": [
        "<matplotlib.figure.Figure at 0x109e56410>"
       ]
      }
     ],
     "prompt_number": 23
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### Step Size"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "params = [0.01, 0.025, 0.05, 0.1, 1.0]\n",
      "metrics = [evaluate(train_data, test_data, 10, param, 0.0, 'l2', False) for param in params]\n",
      "print params\n",
      "print metrics\n",
      "plot(params, metrics)\n",
      "fig = matplotlib.pyplot.gcf()\n",
      "pyplot.xscale('log')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[0.01, 0.025, 0.05, 0.1, 1.0]\n",
        "[1.4869656275309227, 1.4189071944747715, 1.5027293911925559, 1.5384660954019971, nan]\n"
       ]
      },
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "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\nagAAAABJRU5ErkJggg==\n",
       "text": [
        "<matplotlib.figure.Figure at 0x109bb5e90>"
       ]
      }
     ],
     "prompt_number": 24
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### L2 Regularization"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "params = [0.0, 0.01, 0.1, 1.0, 5.0, 10.0, 20.0]\n",
      "metrics = [evaluate(train_data, test_data, 10, 0.1, param, 'l2', False) for param in params]\n",
      "print params\n",
      "print metrics\n",
      "plot(params, metrics)\n",
      "fig = matplotlib.pyplot.gcf()\n",
      "pyplot.xscale('log')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[0.0, 0.01, 0.1, 1.0, 5.0, 10.0, 20.0]\n",
        "[1.5384660954019973, 1.5379108106882864, 1.5329809395123755, 1.4900275345312988, 1.4016676336981468, 1.40998359211149, 1.5381771283158705]\n"
       ]
      },
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "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\n0lROptp7GAAAAABJRU5ErkJggg==\n",
       "text": [
        "<matplotlib.figure.Figure at 0x1095c0410>"
       ]
      }
     ],
     "prompt_number": 25
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### L1 Regularization"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "params = [0.0, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0]\n",
      "metrics = [evaluate(train_data, test_data, 10, 0.1, param, 'l1', False) for param in params]\n",
      "print params\n",
      "print metrics\n",
      "plot(params, metrics)\n",
      "fig = matplotlib.pyplot.gcf()\n",
      "pyplot.xscale('log')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[0.0, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0]\n",
        "[1.5384660954019973, 1.5384518080419873, 1.5383237472930684, 1.5372017600929164, 1.5303809928601677, 1.4352494587433793, 4.7551250073268614]\n"
       ]
      },
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "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\nSSn2/5CSKAlkr5P+AAAAAElFTkSuQmCC\n",
       "text": [
        "<matplotlib.figure.Figure at 0x1097ad8d0>"
       ]
      }
     ],
     "prompt_number": 26
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# Investigate sparsity of L1-regularized solution\n",
      "model_l1 = LinearRegressionWithSGD.train(train_data, 10, 0.1, regParam=1.0, regType='l1', intercept=False)\n",
      "model_l1_10 = LinearRegressionWithSGD.train(train_data, 10, 0.1, regParam=10.0, regType='l1', intercept=False)\n",
      "model_l1_100 = LinearRegressionWithSGD.train(train_data, 10, 0.1, regParam=100.0, regType='l1', intercept=False)\n",
      "print \"L1 (1.0) number of zero weights: \" + str(sum(model_l1.weights.array == 0))\n",
      "print \"L1 (10.0) number of zeros weights: \" + str(sum(model_l1_10.weights.array == 0))\n",
      "print \"L1 (100.0) number of zeros weights: \" + str(sum(model_l1_100.weights.array == 0))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "L1 (1.0) number of zero weights: 4\n",
        "L1 (10.0) number of zeros weights: 20\n",
        "L1 (100.0) number of zeros weights: 55\n"
       ]
      }
     ],
     "prompt_number": 27
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### Intercept"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "params = [False, True]\n",
      "metrics = [evaluate(train_data, test_data, 10, 0.1, 1.0, 'l2', param) for param in params]\n",
      "print params\n",
      "print metrics\n",
      "bar(params, metrics, color='lightblue')\n",
      "fig = matplotlib.pyplot.gcf()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[False, True]\n",
        "[1.4900275345312988, 1.506469812020645]\n"
       ]
      },
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "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\nRU5ErkJggg==\n",
       "text": [
        "<matplotlib.figure.Figure at 0x10979e990>"
       ]
      }
     ],
     "prompt_number": 28
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Evaluating the Impact of Different Parameter Settings for Decision Tree Model"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# create a function to evaluate decision tree model\n",
      "def evaluate_dt(train, test, maxDepth, maxBins):\n",
      "    model = DecisionTree.trainRegressor(train, {}, impurity='variance', maxDepth=maxDepth, maxBins=maxBins)\n",
      "    preds = model.predict(test.map(lambda p: p.features))\n",
      "    actual = test.map(lambda p: p.label)\n",
      "    tp = actual.zip(preds)\n",
      "    rmsle = np.sqrt(tp.map(lambda (t, p): squared_log_error(t, p)).mean())\n",
      "    return rmsle"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 29
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### Tree Depth"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "params = [1, 2, 3, 4, 5, 10, 20]\n",
      "metrics = [evaluate_dt(train_data_dt, test_data_dt, param, 32) for param in params]\n",
      "print params\n",
      "print metrics\n",
      "plot(params, metrics)\n",
      "fig = matplotlib.pyplot.gcf()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[1, 2, 3, 4, 5, 10, 20]\n",
        "[1.0280339660196287, 0.92686672078778276, 0.81807794023407532, 0.74060228537329209, 0.63583503599563096, 0.42670792592513562, 0.4583644474027882]\n"
       ]
      },
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "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\nAQg/XPiIsT5JAAAAAElFTkSuQmCC\n",
       "text": [
        "<matplotlib.figure.Figure at 0x109e67650>"
       ]
      }
     ],
     "prompt_number": 30
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### Max Bins"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "params = [2, 4, 8, 16, 32, 64, 100]\n",
      "metrics = [evaluate_dt(train_data_dt, test_data_dt, 5, param) for param in params]\n",
      "print params\n",
      "print metrics\n",
      "plot(params, metrics)\n",
      "fig = matplotlib.pyplot.gcf()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[2, 4, 8, 16, 32, 64, 100]\n",
        "[1.3069788763726049, 0.81923394899750324, 0.75651792347650992, 0.61793665178800294, 0.63545550484501234, 0.63583503599563096, 0.63583503599563096]\n"
       ]
      },
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "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\n",
       "text": [
        "<matplotlib.figure.Figure at 0x10a42fa10>"
       ]
      }
     ],
     "prompt_number": 31
    }
   ],
   "metadata": {}
  }
 ]
}